#!/bin/bash
# From https://www.kernel.org/doc/html/v6.1/process/submit-checklist.html
# "Has been tested with CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES, CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_ATOMIC_SLEEP, CONFIG_PROVE_RCU and CONFIG_DEBUG_OBJECTS_RCU_HEAD all simultaneously enabled"
# We add on a few more locking-related kconfigs.
# Note-
# 1. CONFIG_DEBUG_SLAB won't be enabled as we typically select SLUB as the memory allocator
# 2. CONFIG_PROVE_RCU_LIST also won't even show up in the menu until CONFIG_RCU_EXPERT=y

name=$(basename $0)

usage()
{
echo "Usage: ${name} [kernel-config-file]
Checks given kernel config for a few of the required configs for patch submission
(mostly debug stuff)"
}

[[ $1 = "-h" ]] && {
  usage ; exit 0
}
if [[ $# -eq 1 ]] ; then
   KCONFIG=$1
else
   # NOTE! ASSUMING arch is x86_64
   KCONFIG=/boot/config-$(uname -r)
fi

[[ ! -f ${KCONFIG} ]] && {
   echo "${name}: kernel config file ${KCONFIG} not found, aborting" ; exit 1
}
echo "Kernel config file: ${KCONFIG}"

# From https://www.kernel.org/doc/html/v6.1/process/submit-checklist.html
# points #s 12, 13, 14.
# The kconfigs following CONFIG_SMP are the lockdep-related ones.
KCONFIGS_ARR=(CONFIG_PREEMPT CONFIG_DEBUG_PREEMPT CONFIG_DEBUG_SLAB \
 CONFIG_DEBUG_PAGEALLOC CONFIG_DEBUG_MUTEXES CONFIG_DEBUG_SPINLOCK \
 CONFIG_DEBUG_ATOMIC_SLEEP CONFIG_PROVE_RCU CONFIG_DEBUG_OBJECTS_RCU_HEAD \
 CONFIG_SMP \
 CONFIG_PROVE_LOCKING CONFIG_LOCKDEP CONFIG_DEBUG_RT_MUTEXES CONFIG_DEBUG_RWSEMS \
 CONFIG_DEBUG_WW_MUTEX_SLOWPATH CONFIG_DEBUG_LOCK_ALLOC CONFIG_PREEMPT_COUNT \
 CONFIG_TRACE_IRQFLAGS CONFIG_LOCK_STAT CONFIG_PROVE_RCU_LIST)

for KCONF in "${KCONFIGS_ARR[@]}" ; do
    YES=0 ; MOD=0 ; NO=0
    printf "checking for %-30s" ${KCONF}

    grep -w "${KCONF}" ${KCONFIG} >/dev/null 2>&1
    [[ $? -ne 0 ]] && {
	printf "   [not found]\n"
	if [[ "${KCONF}" = "CONFIG_PROVE_RCU" || "${KCONF}" = "CONFIG_PROVE_RCU_LIST" ]] ; then
	   printf " To enable, set CONFIG_PROVE_LOCKING=y and CONFIG_RCU_EXPERT=y
 (in 'Kernel Hacking / Lock debugging ... / Lock debugging: prove locking correctness' and 'General Setup / RCU Subsystem' resp)\n"
	fi
	continue
    }
    grep "^${KCONF}=y$" ${KCONFIG} >/dev/null 2>&1
    [[ $? -eq 0 ]] && YES=1
    grep "^${KCONF}=m$" ${KCONFIG} >/dev/null 2>&1
    [[ $? -eq 0 ]] && MOD=1
    grep "^# ${KCONF} is not set$" ${KCONFIG} >/dev/null 2>&1
    [[ $? -eq 0 ]] && NO=1

    [[ ${YES} -eq 1 ]] && printf "   Y\n"
    [[ ${MOD} -eq 1 ]] && printf "   M\n"
    [[ ${NO} -eq 1 ]]  && {
	printf "   N\n"
	if [[ "${KCONF}" = "CONFIG_PROVE_LOCKING" ]] ; then
	   printf " To enable, turn On 'Kernel Hacking / Lock debugging ... / Lock debugging: prove locking correctness'\n"
        fi
    }
done
exit 0
